from . import toolean as toolean

import numpy as np
# import sqlite3 as sqlite3

class tooleannet:
    def __init__(self, dbname, ci ,ch, co):
        
        #self.con = sqlite3.connect(dbname)
        # self.inode=((np.random.rand(1,ci))>0)[0].tolist()
        # self.hnode=((np.random.rand(1,ch))>0)[0].tolist()
        # self.onode=((np.random.rand(1,co))>0)[0].tolist()
        self.inode = toolean.rand_tv(ci)
        self.hnode = toolean.rand_tv(ch)
        self.onode = toolean.rand_tv(co)
        # self.wi=((np.random.rand(ch,ci))>0.5)
        self.wi = toolean.rand_tm(ch,ci)
        # self.wo=((np.random.rand(co,ch))>0.5)
        self.wo = toolean.rand_tm(co,ch)
    def feedforward(self):
        self.hnode=toolean.otimes_tv_tm(self.inode,self.wi)
        self.onode=toolean.otimes_tv_tm(self.hnode,self.wo)
    def feedbackward(self):
        self.hnode=toolean.otimes_tv_tm(self.onode,self.wo.T)
        self.inode=toolean.otimes_tv_tm(self.hnode,self.wi.T)
    def backPropagate(self, targets):        
        #calculate error
        self.onode_error=toolean.qtimes_tv_tv(targets,self.onode)
        #self.wo=boolean.otimes_bv_bm(error,self.wo)
        #self.hnodetargets=boolean.otimes_bv_bm(self.error, np.transpose(self.wo))
        #self.hnode_error=[boolean.otimes_b_b(x,y) for x,y in zip(self.hnodetargets,self.hnode)]
        #modify out weight matrix
        self.wo=(toolean.qtimes_tv_tm(self.onode_error,self.wo.T)).T
        #calculate hnode error
        self.hnodetargets=toolean.otimes_tv_tm(targets,self.wo.T)
        self.hnode_error=toolean.qtimes_tv_tv(self.hnodetargets,self.hnode)
        self.hnode=self.hnodetargets
        #modify input weight matrix
        # wi_ar = np.array(self.wi)
        self.wi=(toolean.qtimes_tv_tm(self.hnode_error,self.wi.T)).T
        self.inode=toolean.otimes_tv_tm(self.hnode,self.wi.T)
    def forwardPropagate(self, targets):        
        #calculate error
        self.inode_error=toolean.qtimes_tv_tv(targets,self.inode)

        #modify in weight matrix
        self.wi=(toolean.qtimes_tv_tm(self.inode_error,self.wi))
        #calculate hnode error
        self.hnodetargets=toolean.otimes_tv_tm(targets,self.wi)
        self.hnode_error=toolean.qtimes_tv_tv(self.hnodetargets,self.hnode)
        self.hnode=self.hnodetargets
        #modify output weight matrix
        self.wo=(toolean.qtimes_tv_tm(self.hnode_error,self.wo))
        self.onode=toolean.otimes_tv_tm(self.hnode,self.wo)

    def train(self,inputs,targets):
            #
        inputs_flip=[x*(-1) for x in inputs]
        targets_flip=[x*(-1) for x in targets]
        #
        self.inode=inputs
        self.feedforward()
        self.backPropagate(targets)
##
        self.onode=targets_flip
        self.feedbackward()
        self.forwardPropagate(inputs_flip)
#

        #
        self.inode=inputs
        self.feedforward()




